import { ICommandHandler, ICommandOption, IDisposable } from '../interface';
import { CommandsRegistry } from './command-register';

/**
 * 指令控制器
 *
 * @author chitanda
 * @date 2022-06-28 19:06:51
 * @export
 * @class CommandController
 */
export class CommandController {
  private commandRegister = new CommandsRegistry();

  /**
   * 注册指令
   *
   * @author chitanda
   * @date 2022-06-28 19:06:45
   * @param {string} id
   * @param {ICommandHandler} handler
   * @param {ICommandOption} [opts]
   * @return {*}  {IDisposable}
   */
  register(id: string, handler: ICommandHandler, opts?: ICommandOption): IDisposable {
    return this.commandRegister.registerCommand(id, handler, opts);
  }

  /**
   * 执行指令
   *
   * @author chitanda
   * @date 2022-06-28 19:06:38
   * @template T
   * @param {string} id
   * @param {...unknown[]} args
   * @return {*}  {Promise<T>}
   */
  async execute<T = undefined>(id: string, ...args: unknown[]): Promise<T> {
    const command = this.commandRegister.getCommand(id);
    if (command) {
      return command.handler(...args) as T | Promise<T>;
    }
  }

  /**
   * 判断指令是否存在，可直接抛出异常
   *
   * @author chitanda
   * @date 2022-06-28 19:06:11
   * @param {string} id
   * @param {boolean} [err]
   * @return {*}  {boolean}
   */
  hasCommand(id: string, err?: boolean): boolean {
    const bol = !!this.commandRegister.hasCommand(id);
    if (err === true && bol === true) {
      throw new Error(`未注册指令: ${id}，请先注册指令`);
    }
    return bol;
  }

  getCommandOpts(id: string): ICommandOption | undefined {
    return this.commandRegister.getCommandOpt(id);
  }
}
